package seguranca.manager;

import geral.manager.GenericManager;
import geral.manager.UtilManager;
import geral.util.FacesUtil;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.enterprise.context.ConversationScoped;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.inject.Inject;
import javax.inject.Named;

import aspecto.annotation.Permissao;
import br.com.sgc.entities.seguranca.Perfil;
import br.com.sgc.exception.ValidacaoException;
import br.com.sgc.permissao.Role;
import br.com.sgc.permissao.RoleComparator;
import br.com.sgc.session.GenericSession;

@Named
@ConversationScoped
public class PerfilManager extends GenericManager implements Serializable{

	private static final long serialVersionUID = -2390437761173912015L;
	
	private Perfil perfil = new Perfil();
	private List<Perfil> listPerfil = new ArrayList<Perfil>();
	
	private List<Role> source = new ArrayList<Role>();
	private List<Role> target = new ArrayList<Role>();
	private List<SelectItem> listRoles = new ArrayList<SelectItem>();
	
	
	private String filterModulo = "";
	private String filterAplicacao = "";
	private Role role;
	
	@EJB
	private GenericSession<Perfil> perfilSession;
	
	@Inject
	private UtilManager utilManager;
	
	private Boolean showPanelCadastro;
	
	@Permissao(role = Role.Sistema_Usuarios_Perfil_Listar)
	public String list(){
		listPerfil = perfilSession.findAll(Perfil.class, utilManager.getSegurancaManager().getUsuarioLogado().getClinica().getId());
		prepareSave();
		showPanelCadastro = false;
		return "formPerfil";
	}
	
	@Permissao(role = Role.Sistema_Usuarios_Perfil_Salvar)
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public String prepareSave(){
		filterModulo = "";
		source = new ArrayList<Role>();
		target = new ArrayList<Role>();
		perfil = new Perfil();
		perfil.setClinica(utilManager.getSegurancaManager().getUsuarioLogado().getClinica());
		showPanelCadastro = true;
		return "formPerfil";
	}
	
	@Permissao(role = Role.Sistema_Usuarios_Perfil_Salvar)
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public String save() {

		if(target.isEmpty()){
			FacesUtil.mensErro("N�o foi selecionado nenhuma permiss�o");
			return null;
		}
		fillPermissao();

		try {
			perfilSession.save(perfil);
			FacesUtil.mensInfo("Salvo com Sucesso!");
			return list();
			
		// Erros de negócio
		} catch (ValidacaoException e) {
			e.printStackTrace();
			FacesUtil.mensWarn(e.getMessage());
		}

		return null;
	}

	private void fillPermissao() {
		String perm = "";
		for(Role permissao: target){
			perm += permissao.name()+",";
		}
		if(!perm.equals("")){
			perm = perm.substring(0,perm.length()-1);
		}
		perfil.setPermissoes(perm);
		
		
	}
	
	@Permissao(role = Role.Sistema_Usuarios_Perfil_Atualizar)
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public String prepareUpdate(){
		
		source = new ArrayList<Role>();
		target = new ArrayList<Role>();
		perfil = perfilSession.findById(Perfil.class, perfil.getId());
		perfil.setClinica(utilManager.getSegurancaManager().getUsuarioLogado().getClinica());
		if(perfil.getPermissoesArray() != null ){
			for(String permissao : perfil.getPermissoesArray()){
				target.add(Role.findRole(permissao));
			}
			Collections.sort(target, new RoleComparator());
		}
		source.removeAll(target);
		showPanelCadastro = true;
		
		return "formPerfil";
	}
	
	@Permissao(role = Role.Sistema_Usuarios_Perfil_Atualizar)
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public String update() {

		if(target.isEmpty()){
			FacesUtil.mensErro("N�o foi selecionado nenhuma permiss�o");
			return null;
		}
		fillPermissao();

		try {
			perfilSession.update(perfil);
			FacesUtil.mensInfo("Atualizado com Sucesso!");
			return list();
		
		// Erros de negócio
		} catch (ValidacaoException e) {
			e.printStackTrace();
			FacesUtil.mensWarn(e.getMessage());
		}

		return null;
	}
	
	@Permissao(role = Role.Sistema_Usuarios_Perfil_Excluir)
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public String delete() {

		try {
			perfilSession.delete(perfil);
			FacesUtil.mensInfo("Exclu�do com Sucesso!");
			return list();

		// Erros de negócio
		} catch (ValidacaoException e) {
			FacesUtil.mensErro("Imposs�vel Excluir!");
		}

		return null;
	}
	
	public void filterAplicacoes(ValueChangeEvent event){
		listRoles.clear();
		filterAplicacao = (String) event.getNewValue();
		
		if(utilManager.getSegurancaManager().getUsuarioLogado().isSuperUsuario()){
			for(Role tipo: Role.getRolesByAplicacao(filterAplicacao)){
				listRoles.add(new SelectItem(tipo.getModulo(),tipo.getModulo()));
			} 
		} else {
			for(Role tipo: Role.getRolesByAplicacaoPerfil(filterAplicacao, utilManager.getSegurancaManager().getUsuarioLogado().getPerfilUsuario().getPermissoes())){
				listRoles.add(new SelectItem(tipo.getModulo(),tipo.getModulo()));
			}
		}
	}
	
	public void filterRoles(ValueChangeEvent event){
		filterModulo = (String) event.getNewValue();
		source = new ArrayList<Role>();
		if(utilManager.getSegurancaManager().getUsuarioLogado().isSuperUsuario()){
			for(Role r: Role.getRolesByModulo(filterModulo)){
				source.add(r);
			}
		} else {
			for(Role r: Role.getRolesByModuloPerfil(filterModulo, utilManager.getSegurancaManager().getUsuarioLogado().getPerfilUsuario().getPermissoes())){
				source.add(r);
			}
		}
		source.removeAll(target);
	}
	
	
	// ================================================================================= //
	
	public List<SelectItem> getRoleAplicacoes() {

		List<SelectItem> listSeList = new ArrayList<SelectItem>();
		if(utilManager.getSegurancaManager().getUsuarioLogado().isSuperUsuario()){
			for(Role tipo: Role.getAplicacoes().values()){
				listSeList.add(new SelectItem(tipo.getAplicacao(),tipo.getAplicacao()));
			} 
		} else {
			for(Role tipo: Role.aplicacoesByPerfil(utilManager.getSegurancaManager().getUsuarioLogado().getPerfilUsuario().getPermissoesArray()).values()){
				listSeList.add(new SelectItem(tipo.getAplicacao(),tipo.getAplicacao()));
			}
		}

		return listSeList;
	}
	
	public String addPermissao(){
		target.add(role);
		source.remove(role);
		return null;
	}
	
	public String removePermissao(){
		target.remove(role);
		source.add(role);
		return null;
	}

	public void addAll(){
		target.addAll(source);
		source.removeAll(target);
	}
	
	public void removeAll(){
		target.removeAll(source);
		source.addAll(target);
	}
	
	public Perfil getPerfil() {
		return perfil;
	}

	public void setPerfil(Perfil perfil) {
		this.perfil = perfil;
	}

	public List<Perfil> getListPerfil() {
		return listPerfil;
	}

	public void setListPerfil(List<Perfil> listPerfil) {
		this.listPerfil = listPerfil;
	}

	public String getFilterModulo() {
		return filterModulo;
	}

	public void setFilterModulo(String filterModulo) {
		this.filterModulo = filterModulo;
	}

	public Role getRole() {
		return role;
	}

	public void setRole(Role role) {
		this.role = role;
	}

	public List<Role> getSource() {
		return source;
	}

	public void setSource(List<Role> source) {
		this.source = source;
	}

	public List<Role> getTarget() {
		return target;
	}

	public void setTarget(List<Role> target) {
		this.target = target;
	}

	public String getFilterAplicacao() {
		return filterAplicacao;
	}

	public void setFilterAplicacao(String filterAplicacao) {
		this.filterAplicacao = filterAplicacao;
	}

	public List<SelectItem> getListRoles() {
		return listRoles;
	}

	public void setListRoles(List<SelectItem> listRoles) {
		this.listRoles = listRoles;
	}

	public Boolean getShowPanelCadastro() {
		return showPanelCadastro;
	}

	public void setShowPanelCadastro(Boolean showPanelCadastro) {
		this.showPanelCadastro = showPanelCadastro;
	}

	public GenericSession<Perfil> getPerfilSession() {
		return perfilSession;
	}

	public void setPerfilSession(GenericSession<Perfil> perfilSession) {
		this.perfilSession = perfilSession;
	}
	
	
}
